import CryptoJS from 'crypto-js';
// 通用Excel导出工具
import * as XLSX from 'xlsx';

// aes加密
function encrypt(str, mykey, myiv) {
  var key = CryptoJS.enc.Utf8.parse(mykey);
  var iv = CryptoJS.enc.Utf8.parse(myiv);
  var srcs = CryptoJS.enc.Utf8.parse(str);
  var encrypted = CryptoJS.AES.encrypt(srcs, key, {
    iv: iv,
    mode: CryptoJS.mode.CBC,
    padding: CryptoJS.pad.Pkcs7,
  });
  return encrypted.ciphertext.toString();
}

// aes解密
function decrypt(str, mykey, myiv) {
  var key = CryptoJS.enc.Utf8.parse(mykey);
  var iv = CryptoJS.enc.Utf8.parse(myiv);
  var encryptedHexStr = CryptoJS.enc.Hex.parse(str);
  var srcs = CryptoJS.enc.Base64.stringify(encryptedHexStr);
  var decrypt = CryptoJS.AES.decrypt(srcs, key, {
    iv: iv,
    mode: CryptoJS.mode.CBC,
    padding: CryptoJS.pad.Pkcs7
  });
  return CryptoJS.enc.Utf8.stringify(decrypt).toString();
}

// 根据平台封装的简单提示
function toast(str) {
  uni.showToast({
    title: str,
    icon: "none",
    duration: 3000 // 延长提示时长，确保用户看清
  });
}

// 成功的提示
function sucToast(str) {
  uni.showToast({
    title: str,
    icon: "success",
    duration: 3000
  });
}

// 加载提示
function showLoading(str) {
  uni.showLoading({
    title: str
  });
}

// 关闭加载提示
function hideLoading() {
  uni.hideLoading();
}

// 获取时间戳
function getTimestamp() {
  return new Date().getTime();
}

// 校验是否登录
function checkLogin() {
  const islogin = uni.getStorageSync('isLogin'); // isLogin是登录成功后在本地存储登录标识
  if (islogin) return true;
  else return false;
}

// 本地存储
function saveStorage(str, val) {
  console.log('本地缓存:' + str + '，值：' + val);
  uni.setStorageSync(str, val);
}

// 读取本地存储
function readStorage(str) {
  console.log('准备读取缓存:' + str);
  let val = uni.getStorageSync(str);
  console.log('准备读取缓存:' + str + ',得到' + val);
  return val;
}

// 新增：金额转换为万元，保留两位小数（核心方法）
function formatToWan(num) {
  // 1. 处理空值/非数字情况，避免报错（兼容接口返回null/undefined）
  if (num == null || isNaN(Number(num))) return '0.00';

  // 2. 转换为数字类型，避免字符串计算错误（如接口返回字符串格式的数字）
  const originNum = Number(num);

  // 3. 元转万元（除以10000），保留两位小数（四舍五入，符合财务规范）
  const wanNum = (originNum / 10000).toFixed(2);

  // 4. 可选：如需显示"万元"单位，可改为 `${wanNum} 万元`（当前仅返回数值，标题已标注"万元"）
  return wanNum;
}

// 核心：企业号H5专属Excel导出函数（纯H5原生，支持预览/下载+格式优化）
function exportExcel(data, fileName = '企业数据报表') {
  // 1. 文件名优化：易识别、易搜索，避免特殊字符
  const dateStr = new Date().toLocaleDateString().replace(/\//g, '-'); // 格式：2025-11-17
  fileName = `${fileName}_${dateStr}.xlsx`; // 最终文件名：企业数据报表_2025-11-17.xlsx
  fileName = fileName.replace(/[^\u4e00-\u9fa5a-zA-Z0-9_\-\.]/g, '_'); // 过滤非法字符

  // 2. 数据校验：避免空数据/格式错误导致失败
  let exportData = [];
  try {
    if (!data) { toast('暂无数据可导出'); return; }
    // 支持JSON字符串/对象数组两种输入格式
    if (typeof data === 'string') {
      exportData = JSON.parse(data);
    } else if (Array.isArray(data)) {
      // 过滤数组中非对象的无效数据
      exportData = data.filter(item => typeof item === 'object' && item !== null);
    } else {
      toast('数据格式错误，仅支持对象数组导出'); return;
    }
    // 无有效数据则终止
    if (exportData.length === 0) { toast('无有效数据可导出'); return; }
  } catch (err) {
    console.error('数据处理失败：', err);
    toast('导出失败，请检查数据格式');
    return;
  }

  // 3. Excel生成：格式优化（黑边框+标题黑粗体+列宽加大）
  const ws = XLSX.utils.json_to_sheet(exportData);
  const wb = XLSX.utils.book_new();
  XLSX.utils.book_append_sheet(wb, ws, "Sheet1");

  // ================= 格式优化核心配置 =================
  // 3.1 定义样式：黑边框 + 标题粗体
  const borderStyle = { // 黑边框样式
    top: { style: 'thin', color: { rgb: '000000' } },
    bottom: { style: 'thin', color: { rgb: '000000' } },
    left: { style: 'thin', color: { rgb: '000000' } },
    right: { style: 'thin', color: { rgb: '000000' } }
  };
  const titleFontStyle = { // 标题粗体样式
    font: { bold: true },
    alignment: { horizontal: 'center' } // 标题居中（可选优化）
  };

  // 3.2 处理表头（第一行）：黑粗体 + 黑边框
  const headerRow = 0; // 表头在第0行
  Object.keys(exportData[0]).forEach((key, colIndex) => {
    const cellAddress = XLSX.utils.encode_cell({ r: headerRow, c: colIndex });
    // 表头样式：粗体 + 居中 + 黑边框
    ws[cellAddress].s = { ...titleFontStyle, border: borderStyle };
  });

  // 3.3 处理内容行：所有单元格加黑边框
  exportData.forEach((rowData, rowIndex) => {
    const dataRow = rowIndex + 1; // 内容行从第1行开始
    Object.keys(rowData).forEach((key, colIndex) => {
      const cellAddress = XLSX.utils.encode_cell({ r: dataRow, c: colIndex });
      // 内容单元格样式：黑边框 + 默认字体
      ws[cellAddress].s = { border: borderStyle };
    });
  });

  // 3.4 列宽加大（比原来宽4个单位，最大25）
  const columnWidths = Object.keys(exportData[0]).map(key => {
    const maxLen = exportData.reduce((max, item) => {
      const val = item[key]?.toString() || '';
      const len = val.replace(/[^\x00-\xff]/g, 'aa').length; // 中文转双字符计算长度
      return Math.max(max, len, key.length); // 至少不小于列名长度
    }, 0);
    return { wch: Math.min(maxLen + 4, 25) }; // 列宽+4（比原来大），最大25
  });
  ws['!cols'] = columnWidths;
  // ===================================================

  // 辅助函数：base64转Blob（纯H5原生，兼容所有浏览器）
  function base64ToBlob(base64Data, mimeType) {
    const byteCharacters = atob(base64Data);
    const byteArrays = [];
    for (let offset = 0; offset < byteCharacters.length; offset += 512) {
      const slice = byteCharacters.slice(offset, offset + 512);
      const byteNumbers = new Array(slice.length);
      for (let i = 0; i < slice.length; i++) {
        byteNumbers[i] = slice.charCodeAt(i);
      }
      byteArrays.push(new Uint8Array(byteNumbers));
    }
    return new Blob(byteArrays, { type: mimeType });
  }

  // 4. 纯H5下载+预览核心逻辑（适配企业微信/微信/其他浏览器）
  showLoading('正在生成文件...');
  const isWXWork = navigator.userAgent.includes('wxwork'); // 企业微信环境
  const isWechat = navigator.userAgent.includes('MicroMessenger') && !isWXWork; // 微信环境

  try {
    // 生成base64格式Excel（兼容性最强）
    const base64Data = XLSX.write(wb, { type: 'base64', bookType: 'xlsx' });
    // Excel标准MIME类型，确保系统正确识别
    const mimeType = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';
    const blob = base64ToBlob(base64Data, mimeType);
    const fileUrl = URL.createObjectURL(blob);

    // 企业微信环境：纯H5触发内置预览（核心功能）
    if (isWXWork) {
      const previewLink = document.createElement('a');
      previewLink.href = fileUrl;
      previewLink.download = fileName;
      previewLink.target = '_blank'; // 新窗口打开触发预览
      previewLink.rel = 'noopener noreferrer';
      previewLink.style.display = 'none';
      document.body.appendChild(previewLink);

      // 模拟点击触发预览
      previewLink.click();

      // 清理资源+提示用户操作
      setTimeout(() => {
        document.body.removeChild(previewLink);
        URL.revokeObjectURL(fileUrl);
        hideLoading();
        toast('文件已打开！右上角···可保存/转发');
      }, 1000);
    }

    // 微信环境：下载后给出清晰查找指引
    else if (isWechat) {
      const downloadLink = document.createElement('a');
      downloadLink.href = fileUrl;
      downloadLink.download = fileName;
      downloadLink.style.display = 'none';
      document.body.appendChild(downloadLink);
      downloadLink.click();

      // 清理资源+指引
      setTimeout(() => {
        document.body.removeChild(downloadLink);
        URL.revokeObjectURL(fileUrl);
        hideLoading();
        toast('文件已保存！微信下拉搜「文件」→ 下载');
      }, 1000);
    }

    // 其他浏览器环境：正常下载提示
    else {
      const downloadLink = document.createElement('a');
      downloadLink.href = fileUrl;
      downloadLink.download = fileName;
      downloadLink.style.display = 'none';
      document.body.appendChild(downloadLink);
      downloadLink.click();

      // 清理资源+提示
      setTimeout(() => {
        document.body.removeChild(downloadLink);
        URL.revokeObjectURL(fileUrl);
        hideLoading();
        toast('文件已下载至浏览器默认下载文件夹');
      }, 800);
    }
  } catch (err) {
    hideLoading();
    console.error('导出失败：', err);
    // 错误兜底提示，告知用户查找路径
    if (isWXWork) {
      toast('预览失败！文件已保存至：企业微信→我→文档→下载');
    } else if (isWechat) {
      toast('下载失败！微信下拉搜「文件」查看');
    } else {
      toast('下载失败，请重试');
    }
  }
}

// 导出所有工具函数
export default {
  toast: toast,
  showLoading: showLoading,
  hideLoading: hideLoading,
  sucToast: sucToast,
  getTimestamp: getTimestamp,
  checkLogin: checkLogin,
  encrypt: encrypt,
  decrypt: decrypt,
  saveStorage: saveStorage,
  readStorage: readStorage,
  formatToWan: formatToWan,
  exportExcel: exportExcel
};